#include <stdio.h>
#include <string.h>
#include "3d_model.h"

D3ModelPart::D3ModelPart(float *xyz, int32_t points, uint32_t color, ImageGrid *grid)
{
    this->points = points < 5 ? points : 4;
    memcpy(this->xyz, xyz, sizeof(float) * 3 * this->points);
    this->width = 1;
    this->height = 1;
    this->depth = 1;
    this->color = color;
    this->grid = grid;
};

void D3ModelPart::Print()
{
    int32_t i;
    printf("Part: points/%d WHD/%.2fx%.2fx%.2f ", points, width, height, depth);
    for (i = 0; i < points * 3; i++)
    {
        printf("%.2f ", xyz[i]);
    }
    printf("\r\n");
};


D3Model::D3Model()
{
}

D3Model::~D3Model()
{
    partList.Lock();
    for (CrossList *node = partList.ChildBegin(); node; node = node->Next())
    {
        if (node->value)
        {
            delete (D3ModelPart*)node->value;
            node->value = NULL;
        }
    }
    partList.UnLock();
}

//模型顶点构建,返回index
int32_t D3Model::AddLine(float xyz[6], uint32_t color)
{
    return partList.PushBackChild(
        new CrossList(new D3ModelPart(xyz, 2, color)));
}

int32_t D3Model::AddLine(float x1, float y1, float z1,
            float x2, float y2, float z2,
            uint32_t color)
{
    float xyz[] = {x1, y1, z1, x2, y2, z2};
    return AddLine(xyz, color);
}

int32_t D3Model::AddTriangle(float xyz[9], uint32_t color)
{
    return partList.PushBackChild(
        new CrossList(new D3ModelPart(xyz, 3, color)));
}

int32_t D3Model::AddTriangle(float x1, float y1, float z1,
                float x2, float y2, float z2,
                float x3, float y3, float z3,
                uint32_t color)
{
    float xyz[] = {x1, y1, z1, x2, y2, z2, x3, y3, z3};
    return AddTriangle(xyz, color);
}

int32_t D3Model::AddRect(float xyz[12], uint32_t color, ImageGrid *grid)
{
    return partList.PushBackChild(
        new CrossList(new D3ModelPart(xyz, 4, color, grid)));
}

int32_t D3Model::AddRect(float x1, float y1, float z1,
            float x2, float y2, float z2,
            float x3, float y3, float z3,
            float x4, float y4, float z4,
            uint32_t color, ImageGrid *grid)
{
    float xyz[] = {x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4};
    return AddRect(xyz, color, grid);
}

//整体缩放,取值范围: 0.0 ~ 缩放区间 ~ 1.0 ~ 放大区间 ~ XXX
void D3Model::Zoom(float multiple)
{
    partList.Lock();
    for (CrossList *node = partList.ChildBegin(); node; node = node->Next())
    {
        D3ModelPart *part = (D3ModelPart*)node->value;
        for (int32_t j = 0; j < part->points; j++)
        {
            part->width = part->height = part->depth = multiple;
        }
    }
    partList.UnLock();
}
